package cn.hn.java.summer.nap.service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.rythmengine.Rythm;
import org.rythmengine.conf.RythmConfigurationKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.hn.java.summer.db.BaseDao;
import cn.hn.java.summer.db.multiple.DataSource1;
import cn.hn.java.summer.nap.Config;
import cn.hn.java.summer.nap.model.ModelField;
import cn.hn.java.summer.nap.model.ModelInfo;
import cn.hn.java.summer.utils.FileUtils;

@Service
public class NapService extends BaseDao<DataSource1>{
	
	@Autowired
	private Config config;

	private List<ModelInfo> allModelInfo;
	private List<ModelField> allTableField;
	private String appRoot="";
	
	@PostConstruct
	public void init() throws IOException{
		
		//程序运行根目录
		appRoot=FileUtils.getAppRoot();
		
		//取到所有表信息
		ModelInfo m=new ModelInfo();
		m.setDataBase(config.getDbName());
		allModelInfo=getTableSchemas(m);
		
		//取到所有表字段信息
		allTableField=getTableFields(m);

		//初始化模型信息
		initSchemas();
		
		//不压缩生成的文件内容
		System.setProperty(RythmConfigurationKey.CODEGEN_COMPACT_ENABLED.getKey(), "false");

		System.out.println("===============正在生成model...================");
		//生成模型java文件
		createModelFile();

		System.out.println("===============正在生成controller...================");
		//生成controller文件
		createControllerFile();

		System.out.println("===============正在生成service...================");
		//生成service文件
		createServiceFile();

		System.out.println("===============正在生成sql...================");
		//生成sql文件
		createSqlFile();
		
		System.out.println("===============正在生成hml...================");
		//生成Html文件
		createHtmlFile();
		
		System.out.println("===============生成完毕================");
		System.exit(0);
	}

	/**
	 * 初始化模型信息
	 */
	private void initSchemas() {
		//匹配模型与字段
		for(ModelInfo model : allModelInfo){
			model.setNameSpace(config.getNameSpace());
			//去除表前缀作为模型类名
			String modelName=model.getTableName().replace(config.getTablePrefix(), "");
			//去除_大写首字母
			modelName=genCamelName(modelName);
			model.setModelName(modelName);
			
			String tableComment=model.getTableComment();
			String tableNameCn=tableComment;
			//注释格式：  XX表名称(说明)
			//注释中有说明，分离表名称和说明
			if(tableComment.indexOf("(")>0){
				tableNameCn=tableComment.replaceAll("\\(.*\\)", "");
				tableComment=tableComment.replaceAll(".*\\((.*)\\).*", "$1");
			}else{
				tableComment="";
			}

			model.setTableComment(tableComment);
			model.setTableNameCn(tableNameCn);
			
			List<ModelField> fields=new ArrayList<ModelField>();
			for(ModelField field : allTableField){
				if(!field.getTableName().equals(model.getTableName())){
					continue;
				}

				String comment=field.getFieldComment();
				String fieldNameCn=comment;
				//注释格式：  XX字段名称(说明)
				//注释中有说明，分离字段名称和说明
				if(comment.indexOf("(")>0){
					fieldNameCn=comment.replaceAll("\\(.*\\)", "");
					comment=comment.replaceAll(".*\\((.*)\\).*", "$1");
				}else{
					comment="";
				}

				field.setFieldComment(comment);
				field.setFieldNameCn(fieldNameCn);
				
				fields.add(field);
			}
			model.setFields(fields);
		}
	}
	
	/**
	 * 生成骆驼命名
	 * @param name
	 */
	private String genCamelName(String name){
		name=name.toLowerCase();
		String[] arr=name.split("");
		StringBuffer buff=new StringBuffer();
		int pos=-1;
		for(int i=0;i<arr.length;i++){
			if(i==0){
				buff.append(arr[i].toUpperCase());
			}else if(arr[i].equals("_")){
				pos=i;
			}else if(pos+1==i){
				buff.append(arr[i].toUpperCase());
				pos=-1;
			}else{
				buff.append(arr[i]);
			}
		}
		return buff.toString();
	}
	
	/**
	 * 生成模型java文件
	 * @throws IOException 
	 */
	public void createModelFile() throws IOException{
		String templateFile=appRoot+"/config/template/model.template";
		String targetFile=appRoot+"/output/java/"+config.getNameSpace().replace(".", "/")+"/model";
		
		for(ModelInfo model : allModelInfo){
			genTargetFile(templateFile,targetFile+"/"+model.getModelName()+".java",model);
		}
	}
	
	/**
	 * 生成controller文件
	 * @throws IOException 
	 */
	public void createControllerFile() throws IOException{
		String templateFile=appRoot+"/config/template/controller.template";
		String targetFile=appRoot+"/output/java/"+config.getNameSpace().replace(".", "/")+"/controller";
		
		for(ModelInfo model : allModelInfo){
			genTargetFile(templateFile,targetFile+"/"+model.getModelName()+"Controller.java",model);
		}
	}

	/**
	 * 生成service文件
	 * @throws IOException 
	 */
	public void createServiceFile() throws IOException{
		String templateFile=appRoot+"/config/template/service.template";
		String targetFile=appRoot+"/output/java/"+config.getNameSpace().replace(".", "/")+"/service";
		
		for(ModelInfo model : allModelInfo){
			genTargetFile(templateFile,targetFile+"/"+model.getModelName()+"Service.java",model);
		}
	}

	/**
	 * 生成sql文件
	 * @throws IOException 
	 */
	public void createSqlFile() throws IOException{
		String templateFile=appRoot+"/config/template/sql.template";
		String targetFile=appRoot+"/output/sql";
		
		for(ModelInfo model : allModelInfo){
			String fileName=targetFile+"/sql-"+model.getModelName()+".xml";
			String content=genTargetFile(templateFile,fileName,model);
			//清除多余的空行
			content=content.replaceAll("(\\s+\\n){2}", "\n");
			org.apache.commons.io.FileUtils.write(new File(fileName), content, false);
		}
	}
	
	/**
	 * 生成html文件
	 * @throws IOException 
	 */
	public void createHtmlFile() throws IOException{
		
		//列表页面html
		String templateFile=appRoot+"/config/template/list.html.template";
		String targetFile=appRoot+"/output/html/";
		
		for(ModelInfo model : allModelInfo){
			genTargetFile(templateFile,targetFile+model.getModelNameLowerCase()+"/list.html",model);
		}

		//添加页面html
		templateFile=appRoot+"/config/template/add.html.template";
		targetFile=appRoot+"/output/html/";
		
		for(ModelInfo model : allModelInfo){
			genTargetFile(templateFile,targetFile+model.getModelNameLowerCase()+"/add.html",model);
		}

		//修改页面html
		templateFile=appRoot+"/config/template/edit.html.template";
		targetFile=appRoot+"/output/html/";
		
		for(ModelInfo model : allModelInfo){
			genTargetFile(templateFile,targetFile+model.getModelNameLowerCase()+"/edit.html",model);
		}
		
		//查看页面html
		templateFile=appRoot+"/config/template/get.html.template";
		targetFile=appRoot+"/output/html/";
		
		for(ModelInfo model : allModelInfo){
			genTargetFile(templateFile,targetFile+model.getModelNameLowerCase()+"/get.html",model);
		}
	}
	
	/**
	 * 生成目标文件
	 * @param templateFile
	 * @param targetFile
	 * @param data
	 * @throws IOException
	 */
	public String genTargetFile(String templateFile,String targetFile,Object data) throws IOException{
		//生成目标文件夹
		File distDir=new File(targetFile).getParentFile();
		distDir.mkdirs();
		
		//生成目标内容
		String resultContent = Rythm.render(new File(templateFile), data);
		//保存目标文件
		org.apache.commons.io.FileUtils.write(new File(targetFile), resultContent);
		return resultContent;

	}
	
	/**
	 * 取数据库中所有表信息
	 * @param t
	 * @return
	 */
	public List<ModelInfo> getTableSchemas(ModelInfo m){
		return all("getTableSchemas", ModelInfo.class, m);
	}
	
	/**
	 * 取数据库中所有表字段信息
	 * @param t
	 * @return
	 */
	public List<ModelField> getTableFields(ModelInfo m){
		return all("getTableFields", ModelField.class, m);
	}
	
	public static void main(String[] args) {
	}
}
